<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
	<title>AXL Tutorial: TranzAm</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- menu -->
	<div id="navmain">
	<ul>
		<li><a href="index.html">Overview</a></li>
		<li><a href="install.html">Installation</a></li>
		<li><a href="config.html">Configurator</a></li>
		<li><a href="animation.html">Animation</a></li>
		<li><a href="framework.html">Framework</a></li>
		<li><a href="tranzam.html">Tutorial</a></li>
	</ul>
	</div>
	<div id="navsub">
	<ul>
		<li><a href="tranzam.html">Start</a></li>
		<li><a href="tranzam_a1.html">Article 1</a></li>
		<li><a href="tranzam_a2.html">Article 2</a></li>
		<li><a href="tranzam_a3.html">Article 3</a></li>
		<li><a href="tranzam_a4.html">Article 4</a></li>
		<li><a href="tranzam_a5.html">Article 5</a></li>
		<li><a href="tranzam_a6.html">Article 6</a></li>
		<li><a href="tranzam_a7.html">Article 7</a></li>
		<li><a href="tranzam_a8.html">Article 8</a></li>
		<li><a href="tranzam_a9.html">Article 9</a></li>
		<li><a href="tranzam_a10.html">Article 10</a></li>
	</ul><span class="smallprint">This menu will stay fixed with a proper browser.</span>
	<p>
	 <a href="http://jigsaw.w3.org/css-validator/">
	  <img style="border:0;width:88px;height:31px"
		   src="http://jigsaw.w3.org/css-validator/images/vcss" 
		   alt="Valid CSS!" />
	 </a>
	</p>
	<p>
      <a href="http://validator.w3.org/check?uri=referer"><img
          src="http://www.w3.org/Icons/valid-xhtml10"
          alt="Valid XHTML 1.0!" height="31" width="88" /></a>
    </p>
<p><a href="http://www.bloggerheads.com/bbc/"><img src="http://www.bloggerheads.com/bbc/bbc.gif" width="90" height="45"  
alt="Click here to find out why." /></a></p>
<p><a href="http://retrospec.sgn.net" ><img src="retrospec.gif" width="150" alt="Fine games" /></a></p>
	</div>
<!-- menu -->

	<div id="main">
	<a name="files"></a>
<h1>Introduction</h1>
In the previous lesson we loaded the map and scrolled around it using the cursors. In this lesson we
will add the car and instead of scrolling the map using the cursors, we will be scrolling the map using the car (i.e. we will be driving!)


<h1>Structure</h1>
If you are manually creating the project 
    make file then use the one from lesson 2 and additionally you will need to add the file game_car.cpp.
    <br />The file game_car.cpp will be used to store everything about the cars in the game (both the player and the enemies).
    <br />The following files will be changed in this lesson:
    <ul>
    <li>game_transam.cpp: this is the same as the previous lesson, with the exception of the initialisation of an array to store a lookup table for angles</li>
    <li>game_car.cpp: this is our new file that contains information about the cars in the game</li>
    <li>game_game.cpp: again, this will contain the main updates to the game. The logic code (TransAmGameLogic) will remain mostly the same, with the keyboard handling passed from this function to the car class. 
    The drawing code (TransAmGameDrawing) will be updated to draw the car</li>
    </ul>
	<a name="source1"></a>
<h1>TranzAm</h1>
The car will be controlled by the cursor keys and will move on a per-pixel basis, employing some basic acceleration/deceleration mathematics. 
When moving an item around the tile map freely (as in our car), you cannot add it directly to the tile map, instead you store it as a regular sprite
and synchronise it's position with the map. Why? because tile maps work with tiles and the unit of measurement in a tile map is the tile (tile size). 
If our car moved one tile at a time we could store the car as a tile and simply alter the tile array, however our car will be moving in pixels.<br />
In our game, although the car will move around the map when driving, it will always be centred on the screen. There are various ways of displaying scrolling 
games: some use this approach and some have a defined 'window' that the player can move within without the map scrolling. While our way is much 
simpler, the problem arises when you get to the edges of the map - how do you ever get to the edge when you are fixed to the centre? The answer is quite simple in our game - we have more sea around the land!
<br />If you think about it there really isn't any difference between lesson 2 (scrolling using the cursors) and scrolling by using the car - 
the car isn't moving around the view at a different speed to the whole screen scrolling as it is fixed to the centre. The only difference 
is that in the previous lesson we drew from the top-left corner of the screen, and in this lesson the car is at the centre of the screen, requiring us
to offset any location by half the width/height.
<h1>Car</h1>
The class definition for our car is quite simple and is as follows:
<div class="code codeblock">
enum CarDirection {CAR_STRAIGHT,CAR_LEFT,CAR_RIGHT};
enum CarMovement {CAR_FREEWHEELING,CAR_ACCELERATE,CAR_DECELERATE};
class Car
{
public:
	static const int MAXVEL=10;
	Car() {	
			angle=screenx=screeny=angle=0;
			acc=vel=decel=xdistancemoved=ydistancemoved=0;
			mapx=mapy=0.0;
			car=NULL;
	}
	~Car();
	void SetupCar();
	bool NextMove();
	AXL_Projects::Animation* car;
	int screenx,screeny;		//position to draw on the screen
	float mapx, mapy;			//real position in map
	int angle;
	float xdistancemoved,ydistancemoved;		//position moved
	CarMovement Move;
	CarDirection Direction;
private:
	void Accelerate();
	void Decelerate();
	void TurnRight();
	void TurnLeft();
public:
	float acc;
	float vel;
	float decel;
};
</div>
The car (forget about any enemy cars, assume the Car class is purely for our player's car) has the following public data items. These are 
variables that you can use within the game because they are useful. Now I know most people will say you can't have public data items, you need 
to hide them, and that is true, however hiding data has a performance hit and quite frankly I can live with the shame. Think of it as 
using a subset of C++ for all it's benefits over C and you'll get over it:
<ul>
<li>screenx/screeny : the position on the screen to draw - this will always be the centre of the map view</li>
<li>mapx/mapy : you can equate this to the mapXoff/mapYoff we used in lesson 2. These store the actual position of the car within the map, i.e. from the picture on lesson 2, this represents the red rectangle VIEW window</li>
<li>angle : the angle the car is facing. For now we will be using trusty Babyloneon degrees rather than the modern radians</li>
<li>Move : this tells us whether we are accelerating, braking or freewheeling</li>
<li>Direction : this tells us whether we are turning left, right or going straight</li>
<li>xdistancemoved,ydistancemoved : this tells us after each frame how many pixels in each direction the car moved, e.g. the faster the car is moving the more they will increase</li>
<li>car : An AXL animation object that holds the animation/graphics for displaying the car</li></ul>
We are also storing a few private variables to hold our current acceleration, velocity and deceleration.
<br />
Our Car will have the following publically available methods:
<ul>
<li>Car() : the constructor. simply initialises everything</li>
<li>~Car : the destructor. simply frees up any allocated memory for the car</li>
<li>SetupCar() : initialise or re-initialise (reset) the car's values</li>
<li>NextMove() : this is the main method for the car and will update it's movement, perform collision detection, etc</li>
</ul>
We are also storing a few private methods to perform the underlying actions of acceleration, braking and turning.
<br />If you notice, the Car has two positions: one is the position on the actual map (mapx/mapy) and the
other is the location on the screen to draw the car (screenx/screeny).
    <h1>Code Walkthrough (game_car.cpp)</h1>
The method SetupCar() initialises all car variables. 
<br />
Moving the car will be achieved by the following formula (in the method NextMove):<br />
<div class="code">
vel=vel-(acc*0.1)+decel;
xdistancemoved=sin(angle)*vel;
ydistancemoved=cos(angle)*vel;
</div><br />
Where vel is our current Velocity, acc is our current acceleration, decel is our current deceleration. The car's angle (angle) is increased/decreased by the user pressing the left/right cursor keys. Setting this value was just trial and error. In this case 
it is by 9 degrees every two frames, i.e. 4.5 degrees per frame (or if we have 60FPS, 270 degrees per second).
<br />
Velocity (vel) is simply increased or decreased by a number whenever the up or down cursor is presses. Again by trial and error, 0.1 seems a nice enough value for now.
<br />In later lessons, this will be enhanced somewhat. For now, we just want to get our car moving.<br />
<strong>NextMove()</strong> is the main method in game_car.cpp, and is what is called within the game logic function TransAmGameLogic() every frame. The method does the following for now:
<ol>
<li>Sets acceleration to 0 at the start of each frame (in this lesson it isn't actually used) and deceleration to be 0.5 - i.e. we assume that if no keys are pressed the car is decelerating</li>
<li>The keyboard is checked for cursor movement and ESCape (moved from TransAmGameLogic in lesson 2) and the relevant flags set
<li>If accelerating/decelerating the velocity (described above) is altered</li>
<li>If turning, the angle (described above) is altered</li>
<li>A check for the map's boundary is made and if the car is at the edge, it is bounced off it</li>
<li>Using the calculated velocity, the displacement of the car (from the previous frame) is calcuated (as above for [x/y]distancemoved variable)</li>
<li>The car's actual map co-ordinates are adjusted</li>
</ol>

<h1>Code Walkthrough (game_game.cpp)</h1>
    From the previous lesson, we are still using the two variables mapYoff/mapXoff to store the location of the map we wish to draw. 
    However, these two values are calculated from on the Car's member variables mapx/mapy (which store the location of the car). Because mapXoff/mapYoff 
    store the topleft of the drawing buffer, we calculate them using an offset of the Car's mapx/mapy to centre the car on the screen. 
    I guess an advantage of this, is if we have multiple cars on the screen (e.g. enemy cars) we can easily switch view to those (e.g. a demo mode or a split 
    screen mode for two players).
    
    <br />The main call within TransAmGameLogic (our logic function) is as follows:
    <div class="code">
	if(Player->NextMove()) 
	{
		CleanUp();
		return true;
	}</div>
    This calls the NextMove method for the Player's Car (which updates the car's position, handles collision, etc). If ESCape is pressed the NextMove() method will return 'true'
    <br />In the drawing code (TransAmGameDrawing), the only change required is to draw the car. This is done after the background tiles and
    before the foreground tiles. We could equally do it after foreground tiles, it doesn't really matter at present.
    <br />Inside the animations.xml file are the definitions for the graphics we are using. The car is just one graphic (there is no animation for it), 
    and all movements (turning) are performed by using the Allegro rotate_sprite function (using the Car's current angle).
    <br />The rest of the code is basically the same as lesson 2, but just moved around to be a bit neater and to allow for when or if 
    we need to expand any of the functions.
<h1>The Car object</h1>
When creating variables, it's always best to keep the scope as narrow as possible, i.e. don't create globals if you can use local.
Following that insightful bit of knowledge, we reckon that the Player's car will only exist within the game_game.cpp file, as such it is
defined as a file level variable as follows: static Car* Player=NULL;
<br />it is initialised in the setup code as follows: Player=new Car();
<br />it is destroyed when the game ends.
<br />So, all that's left is to compile the code and drive your car. It should look something like the screen below.
<img src="images/tranzam_firstcar.jpg" alt="screenshot" />
<h1>Allegro</h1>
Don't know if you've noticed, but in the lessons so far we have had very little to do with Allegro, other than checking the keyboard and rotating a sprite. 
This is because all of the Allegro code that you would normally write (timers, buffers, etc.) are all performed by the AXL library, leaving you 
to concentrate on writing the game. Which is how it should be.
<h1>Next</h1>
In the next lesson, we'll be making the car's movement a bit better and populating some of the display panel's sections (mileage, distance travelled, fuel, temperature).
</div>
</body>
</html>
